//
//  SHStarRatingView.swift
//  SHStarRatingView
//
//  Created by shihu on 2021/11/3.
//

import UIKit

 protocol SHStarRatingViewDelegate: AnyObject {  // 实现代理
    
    /** 手势评分数值 */
    func starRateView(_ starRateView: SHStarRatingView, currentScorePercent: CGFloat)

}

class SHStarRatingView: UIView {
    
    // MARK : public - 属性
    
    public var allowAnimation: Bool = false  // 是否允许动画，默认为false
    public var allowIncompleteStar: Bool = false // 评分时是否允许不是整星，默认为NO
    public var allowProhibitManuallyStar: Bool = false // 是否禁止手动评分，默认为NO
    public weak var delegate: SHStarRatingViewDelegate? // 代理

    // MARK : public - 函数

    public var scorePercent:CGFloat = 1 {//得分值，范围为0--1，默认为1
        didSet{
            if self.scorePercent < 0 {
                self.scorePercent = 0
            }else if self.scorePercent > 1{
                self.scorePercent = 1
            }
            
            if self.delegate != nil && delegate?.starRateView != nil {
                self.delegate?.starRateView(self, currentScorePercent: scorePercent)
            }
            
            self.setNeedsLayout()
        }
    }
    
    public func setBottomImageName(_ bottomIconStr: String, topIconStr: String, starCount: NSInteger) {
        self.bottomIconStr = bottomIconStr
        self.topIconStr = topIconStr
        self.numberOfStars = starCount
        buildDataAndUI()
    }
    

    // MARK : private - 属性
    
    private let defalutStarNumber = 5 //默认星星的个数
    private let animation_Time_Tnterval = 0.2 //动画时间
    private var foregroundStarView = UIView()
    private var backgroundStarView = UIView()
    private var numberOfStars = 0
    private var bottomIconStr = ""
    private var topIconStr = ""
    
    // MARK : private - 函数
    
    private func buildDataAndUI() {
        scorePercent = 1 // 默认
        allowAnimation = false // 是否允许动画，默认为false
        allowIncompleteStar = false // 评分时是否允许不是整星，默认为NO
        allowProhibitManuallyStar = false // 是否禁止手动评分，默认为NO
        
        self.foregroundStarView = self.createStarViewWithImage(imageName: self.topIconStr)
        self.backgroundStarView = self.createStarViewWithImage(imageName: self.bottomIconStr)
        self.addSubview(self.foregroundStarView)
        self.addSubview(self.backgroundStarView)
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(userTapRateView(gesture:)))
        tapGesture.numberOfTapsRequired = 1
        self.addGestureRecognizer(tapGesture)
    }
    
    private func createStarViewWithImage(imageName: String) -> UIView {
        let view = UIView(frame: self.bounds)
        view.clipsToBounds = true
        view.backgroundColor = .clear
        for index in 0..<self.numberOfStars {
            let imageView = UIImageView(image: UIImage.init(named: imageName))
            imageView.frame = CGRect(x: CGFloat(index) * self.bounds.size.width / CGFloat(self.numberOfStars), y: 0, width: self.bounds.size.width / CGFloat(self.numberOfStars), height: self.bounds.size.height)
            imageView.contentMode = .scaleAspectFit
            view.addSubview(imageView)
        }
        return view
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        let animationTimeInterval = self.allowAnimation ? self.animation_Time_Tnterval : 0
        UIView.animate(withDuration: animationTimeInterval) {[weak self] in
            self?.foregroundStarView.frame = CGRect(x: 0, y: 0, width: (self?.bounds.size.width ?? 0)! * (self?.scorePercent ?? 0)!, height: (self?.bounds.size.height ?? 0)!)
        }
    }
    
}


// MARK: - Private method

extension SHStarRatingView {
    
    @objc private func userTapRateView(gesture: UITapGestureRecognizer) {
        if allowProhibitManuallyStar {
            return
        }
        let tapPoint = gesture.location(in: self)
        let offset = tapPoint.x
        let realStarScore = offset / (self.bounds.size.width / CGFloat(self.numberOfStars))
        let starScore = self.allowIncompleteStar ? Float(realStarScore) : ceilf(Float(realStarScore))
        self.scorePercent = CGFloat(starScore / Float(self.numberOfStars))
    }
     
}

